import libtcodpy as libtcod

import console

class SplashError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

class Splash(object):
    def __init__(self, text, width=None, height=None, border=None, title=None,
                 timeout=None, key_hit=True, wrap=False, center=False,
                 foreground=libtcod.white, background=libtcod.black,
                 foreground_alpha=1.0, background_alpha=1.0):
        self.text = text
        self.border = border
        self.title = title
        self.wrap = wrap
        self.center = center

        lines = self.text.split('\n')
        if height is None:
            self.height = len(lines) + bool(self.border) * 2
        else:
            self.height = height

        if width is None:
            self.width = max([len(line) for line in lines]) + bool(self.border) * 2
        else:
            self.width = width


        self.timeout = timeout
        self.key_hit = key_hit

        self._con = console.Console(self.width, self.height)
        self._bak = None

        self.done = False
        self.started = None

        self._fore = foreground
        self._back = background
        self.foreground_alpha = foreground_alpha
        self.background_alpha = background_alpha

        self._clean = None

        self.draw()

    def remove(self):  # clean up .render()ed window if deleted
        if self._clean:
            self.done = True
            self._bak.blit(0, 0, self.width, self.height, self._clean[0], self._clean[1], self._clean[2])
            self._clean = None

    def draw(self):
        self._con.foreground = self._fore
        self._con.background = self._back
        self._con.clear()

        border = bool(self.border)
        if border:
            self._con.frame(0, 0, self.width, self.height, True, libtcod.BKGND_SET, self.title)

        if self.wrap:
            if self.center:
                self._con.print_center_rect(border, border, self.width - border * 2, self.height - border * 2,
                                            libtcod.BKGND_SET, self.text)
                print int(border), int(border), self.width - border * 2, self.height - border * 2
            else:
                self._con.print_left_rect(border, border, self.width - border * 2, self.height - border * 2,
                                          libtcod.BKGND_SET, self.text)
        else:
            lines = self.text.split('\n')
            for y, row in enumerate(lines):
                for x, col in enumerate(row):
                    self._con.putchar(x + border, y + border, lines[y][x], libtcod.BKGND_SET)

    def show(self, parent, x=0, y=0):
        if not (self.timeout or self.key_hit):
            raise SplashError("Splash.show() must set timeout or key_hit")

        self._bak = console.Console(self.width, self.height)
        if hasattr(parent, 'blit'):
            parent.blit(x, y, self.width, self.height, self._bak, 0, 0) 
        elif parent == 0:
            libtcod.console_blit(0, x, y, self.width, self.height, self._bak, 0, 0)
        else:
            raise console.ConsoleError("Cannot blit from %r" % repr(parent))

        self._con.blit(0, 0, self.width, self.height, parent, x, y, 
                       self.foreground_alpha, self.background_alpha)
        self.started = libtcod.sys_elapsed_seconds()
        self.done = False

        while True:
            libtcod.console_flush()   # Limit FPS
            now = libtcod.sys_elapsed_seconds()
            if self.timeout and (now > (self.timeout + self.started)):
                break
            else:
                key = libtcod.console_check_for_keypress(True)
                if key.vk != libtcod.KEY_NONE:
                    break
        self.done = True

        if self.done:
            self._bak.blit(0, 0, self.width, self.height, parent, x, y)
            libtcod.console_flush()

        return self.done

    def render(self, parent, key=None, x=0, y=0):
        self._clean = (parent, x, y)

        if self._bak == None:
            self._bak = console.Console(self.width, self.height)

            if hasattr(parent, 'blit'):
                parent.blit(x, y, self.width, self.height, self._bak, 0, 0) 
            elif parent == 0:
                libtcod.console_blit(0, x, y, width, height, self._bak, 0, 0)
            else:
                raise console.ConsoleError("Cannot blit from %r" % repr(parent))

            self._con.blit(0, 0, self.width, self.height, parent, x, y, 
                           self.foreground_alpha, self.background_alpha)
            self.started = libtcod.sys_elapsed_seconds()
            self.done = False
        else:
            self._bak.blit(0, 0, self.width, self.height, parent, x, y)
            self._con.blit(0, 0, self.width, self.height, parent, x, y, 
                           self.foreground_alpha, self.background_alpha)

        now = libtcod.sys_elapsed_seconds()
        if self.timeout and (now > (self.timeout + self.started)):
            self.done = True
        elif (key is not None) and self.key_hit:
            self.done = (key.vk != libtcod.KEY_NONE)

        if self.done:
            self._bak.blit(0, 0, self.width, self.height, parent, x, y)

        return self.done

    @property
    def foreground(self):
        return self._fore
    @foreground.setter
    def fourground(self, colour):
        self._fore = colour
        self.draw()

    @property
    def background(self):
        return self._back
    @background.setter
    def fourground(self, colour):
        self._back = colour
        self.draw()



if __name__ == '__main__':
    import random
    import math
    from pprint import pprint

    libtcod.sys_set_fps(30)
    libtcod.console_set_custom_font('fonts/arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
    root = console.RootConsole(80, 40, 'Title')

    colours = [libtcod.red, libtcod.orange, libtcod.yellow, libtcod.chartreuse, libtcod.green, 
               libtcod.sea, libtcod.cyan, libtcod.sky, libtcod.blue, libtcod.violet, libtcod.magenta, 
               libtcod.pink, libtcod.white, libtcod.black, libtcod.grey,
              ] 
    for y in range(40):
        for x in range(80):
            root.set_back(x, y, random.choice(colours), libtcod.BKGND_SET)
    root.flush()

    text = r"""
__________                                     _____                  
\______   \_______   ____    ______  ______   /  _  \    ____  ___.__.
 |     ___/\_  __ \_/ __ \  /  ___/ /  ___/  /  /_\  \  /    \<   |  |
 |    |     |  | \/\  ___/  \___ \  \___ \  /    |    \|   |  \\___  |
 |____|     |__|    \___  >/____  >/____  > \____|__  /|___|  // ____|
                        \/      \/      \/          \/      \/ \/     

 ____  __.                 
|    |/ _| ____  ___.__.   
|      < _/ __ \<   |  |   
|    |  \\  ___/ \___  |   
|____|__ \\___  >/ ____| /\
        \/    \/ \/      \/

"""
    splash = Splash(text, timeout=10, key_hit=True)
    splash.show(root)





    text = r"""
__________                 .__      ___________.__                 ._.
\______   \  ____  _____   |  |     \__    ___/|__|  _____    ____ | |
 |       _/_/ __ \ \__  \  |  |       |    |   |  | /     \ _/ __ \| |
 |    |   \\  ___/  / __ \_|  |__     |    |   |  ||  Y Y  \\  ___/ \|
 |____|_  / \___  >(____  /|____/     |____|   |__||__|_|  / \___  >__
        \/      \/      \/                               \/      \/ \/

"""
    splash = Splash(text, timeout=30, key_hit=True)
    while not splash.done:
        key = libtcod.console_check_for_keypress(True)
        splash.render(root, key)
        root.flush()

        splash.background_alpha = abs(math.cos(math.radians(libtcod.sys_elapsed_seconds() % 90 * 20)))


    print "The original background should be here.  Press any key..."
    root.wait_for_keypress(True)


